package com.ds.lens.data.common.constant;

import com.ds.lens.data.common.error.Code;
import lombok.Getter;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * Description:
 * 常量
 *
 * @author WeiShaoying
 * @date 2019-06-03
 */
public interface Constants {
    int YES = 1;
    int NO = 0;
    String METRIC_VALUE = "metricValue";
    String FORECAST = "forecast";
    String VARIANCE = "variance";
    String TIME_STAMP = "timeStamp";
    String ERROR_RATIO = "errorRatio";
    String DASH = "-";
    String COLON = ":";
    String COMMA = ",";
    String WELL = "#";
    String TRANS_NAME = "transName";
    String PERCENTILES = "PERCENTILES";
    String METRIC_SERVICE_PREFIX = "metricQueryService_";
    String APM = "APM";
    String UMP = "UMP";
    String ON_DUTY = "onduty";
    String METRICS = "metrics";

    String REDIS_KEY_SESSION = "session_";
    String REDIS_KEY_FORGET_PASSWORD = "forget_password_";

    enum MonitorRunStatusEnum {
        /**
         * 正常
         */
        NORMAL(0, "正常"),
        /**
         * 挂起
         */
        SUSPENDED(1, "挂起");

        MonitorRunStatusEnum(int code, String name) {
            this.code = code;
            this.name = name;

        }

        @Getter
        private int code;
        @Getter
        private String name;

    }

    enum IntegrationEnum {
        /**
         * APM
         */
        APM(Constants.APM),
        /**
         * UMP
         */
        UMP(Constants.UMP),
        /**
         * 告警通道集成
         */
        ON_DUTY(Constants.ON_DUTY),
        /**
         * API集成 （metrics）
         */
        METRICS(Constants.METRICS);

        IntegrationEnum(String name) {
            this.name = name;
        }

        @Getter
        private String name;

        private static Map<String, IntegrationEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (IntegrationEnum integrationEnum : IntegrationEnum.values()) {
                innerCacheMap.put(integrationEnum.getName().toUpperCase(), integrationEnum);
            }
        }

        public static IntegrationEnum enumOf(String name) {
            return innerCacheMap.get(name.toUpperCase());
        }

    }

    /**
     *
     */
    enum ApplicationRoleEnum {

        /**
         *
         */
        APPLICATION_ADMIN(1, "app_admin"),
        /**
         *
         */
        APPLICATION_USER(2, "app_user");

        @Getter
        private int code;
        @Getter
        private String name;
        private static Map<Integer, ApplicationRoleEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (ApplicationRoleEnum applicationRoleEnum : ApplicationRoleEnum.values()) {
                innerCacheMap.put(applicationRoleEnum.getCode(), applicationRoleEnum);
            }
        }

        ApplicationRoleEnum(int code, String name) {
            this.code = code;
            this.name = name;
        }

        /**
         * 通过来源数值转换为枚举类型
         */
        public static ApplicationRoleEnum enumOf(int code) {
            return innerCacheMap.get(code) == null ? APPLICATION_USER : innerCacheMap.get(code);
        }
    }

    enum RoleEnum {
        /**
         * 系统管理员
         */
        SYS_ADMIN("sys_admin"),
        /**
         * 普通用户
         */
        USER("user");

        RoleEnum(String name) {
            this.name = name;
        }

        @Getter
        private String name;

    }

    /**
     * 用户类型
     */
    enum UserTypeEnum {

        /**
         * LENS
         */
        LENS(1, "LENS"),
        /**
         * SSO
         */
        SSO(2, "SSO");

        @Getter
        private int code;
        @Getter
        private String name;
        private static Map<Integer, UserTypeEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (UserTypeEnum userTypeEnum : UserTypeEnum.values()) {
                innerCacheMap.put(userTypeEnum.getCode(), userTypeEnum);
            }
        }

        UserTypeEnum(int code, String name) {
            this.code = code;
            this.name = name;
        }

        /**
         * 通过来源数值转换为枚举类型
         */
        public static UserTypeEnum enumOf(int code) {
            return innerCacheMap.get(code) == null ? SSO : innerCacheMap.get(code);
        }
    }

    /**
     *
     */
    enum OperatorEnum {
        /**
         * >
         */
        GREATER(">", "大于"),
        GREATER_OR_EQUAL(">=", "大于等于"),
        EQUAL("==", "等于"),
        LESS("<", "小于"),
        LESS_OR_EQUAL("<=", "小于等于"),
        BETWEEN("between", "介于"),
        UNKNOWN("UNKNOWN", "未知"),
        ;

        @Getter
        private String operator;
        @Getter
        private String desc;

        private static Map<String, OperatorEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (OperatorEnum operatorEnum : OperatorEnum.values()) {
                innerCacheMap.put(operatorEnum.getOperator(), operatorEnum);
            }
        }

        OperatorEnum(String code, String desc) {
            this.operator = code;
            this.desc = desc;
        }

        /**
         * 通过来源数值转换为枚举类型
         */
        public static OperatorEnum enumOf(String code) {
            return innerCacheMap.get(code) == null ? UNKNOWN : innerCacheMap.get(code);
        }
    }

    /**
     * 删除
     */
    interface Deleted {
        /**
         * 已删除
         */
        int YES = Constants.YES;
        /**
         * 未删除
         */
        int NO = Constants.NO;
    }

    /**
     *
     */
    enum EnabledEnum {
        /**
         * 已启用
         */
        ENABLED(Constants.YES, "已启用"),
        /**
         * 未启用
         */
        DISABLED(Constants.NO, "未启用");

        @Getter
        private int code;
        @Getter
        private String desc;
        private static Map<Integer, EnabledEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (EnabledEnum enabledEnum : EnabledEnum.values()) {
                innerCacheMap.put(enabledEnum.getCode(), enabledEnum);
            }
        }

        EnabledEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        /**
         * 通过来源数值转换为枚举类型
         */
        public static EnabledEnum enumOf(int code) {
            return innerCacheMap.get(code);
        }
    }


    /**
     * 规则操作类型
     */
    enum RuleOperationTypeEnum {
        /**
         * 新增
         */
        CREATE(0, "新增"),
        /**
         * 修改
         */
        UPDATE(1, "修改"),
        /**
         * 删除
         */
        DELETE(2, "删除"),
        /**
         * 生效
         */
        ENABLE(3, "生效"),
        /**
         * 失效
         */
        DISABLE(4, "失效"),
        /**
         * 未知
         */
        UNKNOWN(5, "未知");

        @Getter
        private int code;
        @Getter
        private String desc;
        private static Map<Integer, RuleOperationTypeEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (RuleOperationTypeEnum operationTypeEnum : RuleOperationTypeEnum.values()) {
                innerCacheMap.put(operationTypeEnum.getCode(), operationTypeEnum);
            }
        }

        RuleOperationTypeEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        /**
         * 通过来源数值转换为枚举类型
         */
        public static RuleOperationTypeEnum enumOf(int code) {
            return innerCacheMap.get(code) == null ? UNKNOWN : innerCacheMap.get(code);
        }
    }


    /**
     *
     */
    enum RuleConfigTagsTypeEnum {
        /**
         * endpoint
         */
        ENDPOINT(1, "endpoint"),
        UNKNOWN(0, "未知");

        @Getter
        private int code;
        @Getter
        private String desc;

        private static Map<Integer, RuleConfigTagsTypeEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (RuleConfigTagsTypeEnum ruleConfigTagsTypeEnum : RuleConfigTagsTypeEnum.values()) {
                innerCacheMap.put(ruleConfigTagsTypeEnum.getCode(), ruleConfigTagsTypeEnum);
            }
        }

        RuleConfigTagsTypeEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        /**
         * 通过来源数值转换为枚举类型
         */
        public static RuleConfigTagsTypeEnum enumOf(int code) {
            return innerCacheMap.get(code) == null ? UNKNOWN : innerCacheMap.get(code);
        }
    }


    /**
     * 同步endpoint数据时不同维度的请求参数
     */
    enum ReqEndpointParamsEnum {

        AVG_RESPONSE_TIME_DESC("AVG_RESPONSE_TIME", "desc"),
        //        AVG_RESPONSE_TIME_ASC("AVG_RESPONSE_TIME", "asc"),
        RPM_DESC("RPM", "desc"),
        //        RPM_ASC("RPM", "asc"),
        REQUEST_NUM_DESC("REQUEST_NUM", "desc"),
        //        REQUEST_NUM_ASC("REQUEST_NUM", "asc"),
        //        ERROR_NUM_ASC("REQUEST_NUM", "asc"),
        ERROR_NUM_DESC("ERROR_NUM", "desc");

        @Getter
        private String fields;
        @Getter
        private String order;

        ReqEndpointParamsEnum(String fields, String order) {
            this.fields = fields;
            this.order = order;
        }
    }

    /**
     * key by field
     */
    enum KeyByFieldEnum {

        /**
         * appId
         */
        APP_ID("appId", "appCode"),
        /**
         * tierId
         */
        TIER_ID("tierId", "tierCodes"),
        /**
         * zoneId
         */
        ZONE_ID("zoneId", "zoneCodes"),
        /**
         * envId
         */
        ENV_ID("envId", "envCodes"),
        /**
         * resourceTypeId
         */
        RESOURCE_TYPE_ID("resourceTypeId", "sourceTypeCode"),
        /**
         * instanceId
         */
        INSTANCE_ID("instanceId", "instanceCodes"),
        /**
         * endpoint
         */
        ENDPOINT("endpoint", "endpoint");

        @Getter
        private String key;
        @Getter
        private String field;

        KeyByFieldEnum(String key, String field) {
            this.key = key;
            this.field = field;
        }
    }

    /**
     * 指标数据类型
     */
    enum MetricDimensionDataTypeEnum {

        SIMPLE(0, "简单类型"),
        COMPLEX(1, "复杂类型");

        @Getter
        private int code;
        @Getter
        private String desc;

        MetricDimensionDataTypeEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }
    }


    /**
     * 告警发送状态
     */
    enum AlarmNoticeSendStatusEnum {
        /**
         * 发送成功
         */
        SUCCESS(1, "成功"),
        /**
         * 发送失败
         */
        FAILED(0, "失败");

        @Getter
        private int code;
        @Getter
        private String desc;
        private static Map<Integer, AlarmNoticeSendStatusEnum> innerCacheMap = new HashMap<>(values().length);

        static {
            for (AlarmNoticeSendStatusEnum alarmNoticeSendStatusEnum : AlarmNoticeSendStatusEnum.values()) {
                innerCacheMap.put(alarmNoticeSendStatusEnum.getCode(), alarmNoticeSendStatusEnum);
            }
        }

        AlarmNoticeSendStatusEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        public static AlarmNoticeSendStatusEnum enumOf(int code) {
            return innerCacheMap.get(code) == null ? FAILED : innerCacheMap.get(code);
        }

    }

    enum ExternalEventStatusEnum {
        /**
         * 开启事件
         */
        STARTED(0, "started"),
        /**
         * 自动闭合
         */
        AUTO_COMPLETION(1, "auto_completion"),
        /**
         * 正常闭合
         */
        COMPLETION(2, "completion");

        ExternalEventStatusEnum(int code, String name) {
            this.code = code;
            this.name = name;
        }

        @Getter
        private int code;
        @Getter
        private String name;

    }

    /**
     * 错误码枚举常量
     */
    enum ErrorCode implements Code, Serializable {
        /**
         * The rule does not exist.
         */
        RULE_NOT_EXIST(10001, "The rule does not exist. ID: %s"),
        /**
         * Alarm uid cannot be empty.
         */
        ALARM_UID_EMPTY(10002, "Alarm uid cannot be empty !"),
        /**
         * Alarm info does not exist.
         */
        ALARM_INFO_NOT_EXIST(10003, "Alarm info does not exist. uid: %s"),
        /**
         * Alarm rule config does not exist.
         */
        ALARM_RULE_CONFIG_NOT_EXIST(10004, "Alarm rule config does not exist. id: %s"),
        /**
         * Alarm rule config update failed.
         */
        ALARM_RULE_CONFIG_UPDATE_FAILED(10005, "Alarm rule config update failed. id: %s"),
        /**
         * Alarm rule config save failed.
         */
        ALARM_RULE_CONFIG_UPDATE_FAILED_REASON(10006, "Alarm rule config update failed. Reason: %s"),
        /**
         * Alarm rule config save failed.
         */
        ALARM_RULE_CONFIG_SAVE_FAILED_REASON(10007, "Alarm rule config save failed. Reason: %s"),
        /**
         * The maximum number of rules cannot exceed 6.
         */
        ALARM_RULE_CONFIG_RULE_MAXIMUM(10008, "The maximum number of rules cannot exceed %s"),

        RULES_NOT_EXIST(10009, "The rules do not exist. "),
        /**
         * Alarm name mismatch the rule
         */
        ALARM_NAME_MISMATCH_RULE(10010, "Alarm name mismatch the rule."),
        /**
         * Alarm name already exists
         */
        ALARM_NAME_ALREADY_EXISTS(10010, "Alarm name already exists."),
        /**
         * Rule threshold1 is null
         */
        RULE_RULE_THRESHOLD1_IS_NULL(10011, "Rule threshold1 is null."),
        /**
         * Rule threshold2 is null
         */
        RULE_RULE_THRESHOLD2_IS_NULL(10012, "Rule threshold2 is null."),


        /**
         * param error
         */
        PARAM_ERROR(20001, "msg: %s"),
        /**
         * metric value is null.
         */
        METRIC_VALUE_IS_NULL(20002, "metric value is null"),
        NO_METRIC_NAMES(20003, "No metric names."),

        USER_PERMISSIONS(30001, "The user has no current application permissions"),

        NO_PERMISSION(30002, "Insufficient permissions."),

        DATA_NOT_EXIST(30003, "Data does not exist"),

        RECURRING_DATE_EXCEPTION(30004, "Recurring date exception"),

        SCHEDULE_PARAM_EXIST(30005, "monitorId and monitorTags is null"),

        /**
         * dashboard param
         */
        DASHBOARD_MONITOR_INFO_NULL(40001, "monitorId and monitorVersion should not be null"),
        DASHBOARD_MONITOR_ID_NULL(40001, "monitorId should not be null"),


        /**
         * User param
         */
        USERNAME_EXIST(50001, "The username already exists."),
        EMAIL_EXIST(50002, "The email already exists."),
        INSERT_LENS_USER_FAIL(50003, "Failed to add new user."),
        EMAIL_NOT_EXIST(50004, "The email do not exists."),
        TOKEN_INVALIDATION(50005, "Token invalidation."),
        FAILED_TO_RESET_PASSWORD(50006, "Failed to reset password."),

        WRONG_PASSWORD(99995, "The password is wrong."),
        NO_LENS_USER(99996, "The user does not exist."),
        NO_INTEGRATION_EXCEPTION(99997, "No integration"),
        NO_INSTANCE_EXCEPTION(99998, "No corresponding instance found"),
        /**
         * system exception
         */
        SYSTEM_EXCEPTION(99999, "系统异常"),

        ;


        private Integer code;
        private String msg;

        ErrorCode(Integer code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        @Override
        public Integer code() {
            return code;
        }

        @Override
        public String msg(Object... args) {
            return String.format(msg, args);
        }
    }
}
